package cn.yj.alipay.wrapper;

import cn.yj.alipay.service.handler.AbstractAliPay;
import cn.yj.common.emums.PayFrom;
import cn.yj.common.entity.*;
import cn.yj.common.exception.PayException;
import cn.yj.common.interfaces.IPayFromExecutor;
import cn.yj.commons.utils.BigDecimalUtils;
import cn.yj.commons.utils.StringUtils;
import cn.yj.tools.exception.ServiceException;
import cn.yj.wx.pay.service.handler.AbstractWxPay;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayRequest;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundApplyRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeRefundApplyResponse;
import com.google.gson.Gson;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @author 永健
 * @since 2021-09-23 09:39
 */
public class AliPayFromExecutorExecutor implements ApplicationContextAware, IPayFromExecutor<PayResult, AlipayRequest> {
    private static ApplicationContext app;

    public static AliPayFromExecutorExecutor getInstance() {
        if (app == null) {
            throw new ServiceException("未启用支付宝支付");
        }
        return app.getBean(AliPayFromExecutorExecutor.class);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        app = applicationContext;
    }

    @Resource
    private List<AbstractAliPay> aliPays;

    @Override
    public PayResult underOrder(PayFrom from, AlipayRequest request) throws PayException {
        for (AbstractAliPay aliPay : aliPays) {
            if (aliPay.support(from)) {
                return (PayResult) aliPay.underOrder(request);
            }
        }
        throw new ServiceException("找不到适配该支付的处理器");
    }


    @Override
    public AlipayRequest getRequestParams(PayFrom from, Map<String, Object> params) {
        Gson gson = new Gson();
        switch (from) {
            case PC:
                AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest();

                // bizContent 和 bizModel随意选一个
                alipayTradePagePayRequest.setBizModel(gson.fromJson(JSON.toJSONString(params),
                        AlipayTradePagePayModel.class));
                return alipayTradePagePayRequest;
            case H5:
                AlipayTradeWapPayRequest payRequest = new AlipayTradeWapPayRequest();
                // bizContent 和 bizModel随意选一个
                AlipayTradeWapPayModel model = gson.fromJson(JSON.toJSONString(params), AlipayTradeWapPayModel.class);
                payRequest.setBizModel(model);
                return payRequest;
            case APP:
                AlipayTradeAppPayRequest appPayRequest = new AlipayTradeAppPayRequest();
                appPayRequest.setBizModel(gson.fromJson(JSON.toJSONString(params), AlipayTradeAppPayModel.class));
                return appPayRequest;
            default:
                return null;
        }
    }

    @Override
    public PayRefundOrder queryRefundOrder(RefundQueryParams params) throws PayException {
        AbstractAliPay abstractAliPay = aliPays.get(0);
        return abstractAliPay.queryRefundOrder(params);
    }

    @Override
    public AlipayTradeRefundApplyResponse refund(RefundParams params) throws PayException {

        AlipayTradeRefundApplyRequest alipayTradeRefundApplyRequest = new AlipayTradeRefundApplyRequest();
        AlipayTradeRefundModel alipayTradeRefundModel = new AlipayTradeRefundModel();
        alipayTradeRefundModel.setRefundAmount(params.getRefundAmount().toString());
        alipayTradeRefundModel.setOutTradeNo(params.getOutTradeNo());
        alipayTradeRefundModel.setRefundReason(params.getReason());
        alipayTradeRefundModel.setOutRequestNo(params.getOutRefundNo());
        alipayTradeRefundApplyRequest.setBizModel(alipayTradeRefundModel);
        BigDecimal refundAmount = params.getRefundAmount();
        if (StringUtils.isNull(refundAmount) || BigDecimalUtils.isLeftLERight(refundAmount, BigDecimal.ZERO)) {
            throw new PayException("退款金额不能小于/等于0");
        }
        AbstractAliPay abstractAliPay = aliPays.get(0);
        return abstractAliPay.refund(alipayTradeRefundApplyRequest);
    }

    @Override
    public PayOrder queryOrder(String outTradeNo) {
        AbstractAliPay abstractAliPay = aliPays.get(0);
        return abstractAliPay.queryOrder(outTradeNo);
    }


}
